package org.jsea.meta.api.service.dialect;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Locale;

/**
 * --.
 * *
 * author   Jiang.hy
 * create   2022-04-18
 */
public abstract class AbstractMetaApiDialect implements IMetaApiDialect {

    public static IMetaApiDialect builder(String databaseId) {
        if ("mysql".equalsIgnoreCase(databaseId)) {
            return new MetaApiMysqlDialect();
        } else if ("PostgreSQL".equalsIgnoreCase(databaseId)) {
            return new MetaApiPostgreDialect();
        } else if ("oracle".equalsIgnoreCase(databaseId)) {
            return new MetaApiOracleDialect();
        } else if ("oracle12c".equalsIgnoreCase(databaseId)) {
            return new MetaApiOracle12cDialect();
        }
        throw new UnsupportedOperationException("Database dialects are not supported " + databaseId);
    }

    public String formatColumn(String column) {
        return column.toLowerCase(Locale.ENGLISH);
    }

    public static class MetaApiMysqlDialect extends AbstractMetaApiDialect {

        @Override
        public String buildPaginationSql(String sql, int offset, int limit) {
            if (offset == 0) {
                return sql + " limit " + limit;
            }
            return sql + " limit " + limit + " offset " + offset;
        }
    }


    public static class MetaApiPostgreDialect extends AbstractMetaApiDialect {

        @Override
        public String buildPaginationSql(String sql, int offset, int limit) {
            if (offset == 0) {
                return sql + " limit " + limit;
            }
            return sql + " limit " + limit + " offset " + offset;
        }

    }

    public static class MetaApiOracleDialect extends AbstractMetaApiDialect {

        @Override
        public String buildPaginationSql(String sql, int offset, int limit) {
            limit = (offset >= 1) ? (offset + limit) : limit;
            return "select * from (select tmp.*, rownum row_id from (" +
                    sql + " ) tmp where rownum <= " + limit + " ) where row_id > " + offset;
        }

        @Override
        public void rs(ResultSet rs) throws SQLException {
            rs.setFetchSize(500);
        }

    }

    public static class MetaApiOracle12cDialect extends AbstractMetaApiDialect {

        @Override
        public String buildPaginationSql(String sql, int offset, int limit) {
            return sql + " offset " + offset + " rows fetch next " + limit + " rows only";
        }

        @Override
        public void rs(ResultSet rs) throws SQLException {
            rs.setFetchSize(500);
        }
    }
}
